其他
淘宝的互动项目,为什么总会刷爆你的好友圈?
互指的是相互,比如说相互沟通与交流 动指的是动起来,元素动起来,人动起来
项目元素动起来,只有A自己在动 项目和人动起来,A和B或A和C在动,具有一定的交互行为 项目和人动起来,除了A和B或A和C在动,甚至是B和C也能在动
▐ 什么是Web可访问性
▐ 如何构建可访问性应用
网页内容可访问性准则,即Web Content Accessibility Guideline,简称WCAG 2.0「https://www.w3.org/TR/WCAG20/」 可访问的互联网富应用标准,即Web Accessibility Initiative – Accessible Rich Internet Application,简称WAI-ARIA「https://www.w3.org/TR/WCAG20/」
可被感知的(Perceivable):信息以及各种交互元素必须可以被用户看到或者听到 可操作的(Operable):用户可以在产品界面和导航中进行操作,并能使用诸如屏幕阅读器等辅助技术 可被理解的(Understandable):信息的展现和用户的操作交互必须逻辑清晰一致,以便能被用户充分理解 健壮的(Robust):网页和应用程序中的内容必须确保在各个平台和环境中都能正确地展示,包括在使用了辅助技术的情况下
A级通过最基本的可访问性标准 AAA级是通过最高级别的可访问性标准
平等使用:设计不应该歧视任何一类用户 良好的适应性:设计应该对大多数用户的个体偏好和生理情况都良好的适应 简单直观地使用:无论用户的知识水平,阅读能力和精神集中程序如何,设计都应该做到简单直观易理解 确保信息可以被感知:无论用户的周围环境以及自身的感知能力如何,设计都要将信息有效地传达给用户 容错性:当用户做出设计之外的操作时,设计应将用户的操作带来的负面影响限制在最低程度 使用省力:设计应该让用户的操作舒适而高效,不易疲劳 适宜操作的尺寸:无论用户的体型、姿态和移动能力如何,他们都当有合适的大小和空间来进行各种访问与操控
集成和迭代:贯穿整个项目的设计工作都应考虑,而不应仅仅把精力集中在优化产品的视觉效果上。应预先为产品准备好一系列备选方案,然后通过构建原型、测试的迭代过程并根据反馈探索出最佳的设计方案 发散性思维:不要限制自己的想象力,应该仔细审视目前方案是否是最优解而不是匆匆忙忙地开始编写代码实现方案。在项目进入编写代码实现功能的阶段之前,发散性思维往往可以产出具有良好可访问性的创新性解决方案 收敛性思维:结合使用场景去选择最有效的设计方案,对于可访问性设计来说,则是选择最能适应多样的互联网环境并满足多种个性化需求的方案 以人为本:实践设计性思维的关键在于理解用户的欲望、需求和行为习惯,理解了这些才可能确定项目的方向,并利用用户的反馈来优化产品的设计方案 洞察力:想获得良好的洞察力,就必须知道如何才能满足不同用户访问互联网的各种个性化需求,也就是说要去观察用户的使用场景,看看他们做了什么,听听他们说了什么。洞察力来源于同理心,而同理心又可以来源于故事。换句话说,同理心和洞察力,可以激发大家的创造力和发散性思维,最终想出更具创造性的可访问性设计方案
可行的情况下不要假设你的用户在身体、精神、以及感官方面具备相同程度的能力 用户所用的技术能够发送和接收文字,这是你唯一可以做的假设 用户的时间和所用技术属于用户自己,不属于我们。如果没有足够必要的原因,绝对不能控制这些 为任何非文本内容提供足够好的文本描述 通过使用率最广泛的技术接触你的受众 使用简洁的语言传达你的信息 确保你的网站可用、可搜索、可导航 按照语义设计你的内容,内容和呈现方式之间维持独立 通过添加额外功能渐进式地增强基本内容,允许不愿或不能使用这些功能的用户以得体的方式“降级” 遇到新的 Web 技术后,为确保其可访问,也要为这些技术应用上述这些基本原则
H – 人性化(Humanize):有同理心,了解情绪的不同成分 U – 忘却(Unlearn):远离你默认采用的 "针对具体设备进行设计" 的习惯,有能力切换至不同的习惯模式 M – 模型(Model):借助不同角色帮你看到、听到、感受到具体问题,并要考虑行为、节奏、精神状态和系统状态 B – 构建(Build):发展知识、启发性测试法、核心测试技能、测试基础结构,以及可信度 L – 学习(Learn):障碍到底在哪?用户如何感知、理解和操作 E – 实验(Experiment):将自己置身于不同情况下,与设计师和程序员合作并提供反馈
▐ 互动项目构建可访问性的历程
使用最具语义化的HTML标签元素 结构和样式的分离 定义文档的语言类型非常重要 隐藏内容 不要遗忘<img>的alt属性 包含描述性内容链接 使用通俗易懂的语言 允许仅通过键盘访问内容 在必要时使用ARIA
.sr-only:not(:focus):not(:active) {
position: absolute;
height: 1px;
width: 1px;
clip: rect(1px 1px 1px 1px);
clip: rect(1px,1px,1px,1px);
clip-path: polygon(0px 0px, 0px 0px, 0px 0px);
overflow: hidden ;
}
@media (prefers-reduced-motion: reduce) {
* {
animation: none;
}
}
<div role="button">回到首页</div>
角色:这是什么类型的“东西”?比如,它是一个button 状态:它的情况如何?比如disabled、checked 名称:它的名称或标签是什么? 关系:它是否以某种方式与页面中的其他元素相关联?
让辅助技术用户(比如屏幕阅读器)可以理解定制的小部件(Widget) 以编程方式指示元素之间的关系 通知用户动态更新 向辅助技术隐藏不相关的可视内容 未完全重新编码的不可访问内容的修复
某些角色只能作为特定复杂小部件的一部分(详细请见ARIA的角色一节) 一些aria-*属性是全局的 其他aria-*属性只适用于特定的角色 并不是所有的角色或属性都得到一致的支持或实现
不能让非聚焦的元素得到焦点 提供适当的键盘绑定 改变浏览器的行为 自动维护或更新属性 变化可见的UI视觉(除CSS使用特性的选择器重构UI风格之外)
不要使用WAI-ARIA,使用原生HTML标签元素 除非真的需要,否则不要更改原生语义 所有交互式ARIA控件必须与键盘一起使用 不要让可聚焦元素变得中立(Neutralise) 所有交互元素必须有一个可访问的名称
<div
tabindex="0"
role="button">Play</div>
const buttons = document.querySelectorAll('.button');
[...buttons].forEach(button => {
button.addEventListener('click', doSomething);
button.addEventListener('keyup', (event) => {
if (event.key == 'Enter' || event.key == ' ') {
doSomething();
}
});
});
function doSomething() {
console.log('Something!');
}
React A11y https://github.com/reactjs/react-a11y Vue A11y https://github.com/vue-a11y react-axe https://github.com/dequelabs/react-axe vue-axe https://github.com/vue-a11y/vue-axe eslint-plugin-jsx-a11y https://github.com/evcohen/eslint-plugin-jsx-a11y eslint-plugin-vue-a11y https://github.com/maranran/eslint-plugin-vue-a11y agnostic-axe https://github.com/juliettepretot/agnostic-axe
// src/page/index/index.tsx
if (process.env.NODE_ENV !== 'production') {
// Import agnostic axe here.
// Webpack will comment out this code in production.
import('agnostic-axe').then(({ AxeObserver, logViolations }) => {
console.log(`
✔→⚠ℹ💃🏾😃💁👉👉
Minor(小错误)、Moderate(中等的)、Serious(严重的)和Critical(至关重要的); Serious和Critical必须相办法修复
1. 配置文档: https://github.com/juliettepretot/agnostic-axe
2. Axe Core: https://github.com/dequelabs/axe-core
3. https://web.dev/accessibility-scoring/
4. https://web.dev/lighthouse-accessibility/
💁😃💃🏾ℹ⚠→✔👉👉
`);
const MyAxeObserver = new AxeObserver(logViolations);
MyAxeObserver.observe(document);
});
}